<?php

namespace support\middleware;


use Exception;
use support\ErrorCode;
use think\module\Module;
use think\Request;
use think\Response;

class RequestCheck
{
    /**
     * @param Request $request
     * @param callable $next
     * @return Response
     * @throws Exception
     */
    public function process(Request $request, callable $next): Response
    {
        // 从header头获取token
        $XUserInfoBase64 = $request->header('x-userinfo');

        // 请求参数
        $this->param = $request->param();

        if (empty($XUserInfoBase64)) {
            // 错误的header头参数
            APP_DEBUG && trace("Wrong header param.", "DEBUG");
            throw_strack_exception("Wrong header param.", ErrorCode::WRONG_HEADER_PARAM);
        }

        $XUserInfoBase = json_decode(base64_decode($XUserInfoBase64), true);
        $XUserInfoBase['tenant_id'] = $XUserInfoBase['tenant_id'] ?? 0;


        if (!empty($XUserInfoBase) && !empty($XUserInfoBase['id'])) {
            // 初始化项目ID
            $projectId = array_key_exists('project_id', $this->param) ? $this->param['project_id'] : 0;
            // 设置当前module code
            $currentModuleCode = $this->getCurrentModuleCode($request);
            $request->getModuleCode($currentModuleCode);
            $request->getProjectId($projectId);
            $request->getTenantId($XUserInfoBase['tenant_id']);
            $request->getUserUUID($XUserInfoBase['uuid']);
            $request->getUserId($XUserInfoBase['id']);
            $request->getUnionUserId($XUserInfoBase['id']);
            $request->getXUserInfo($XUserInfoBase64);
            // 生成当前请求批次号
            $batchNumber = C('BELONG_SYSTEM') . '_' . string_random(8) . '-' . create_uuid();
            $request->getBatchNumber($batchNumber);
        } else {
            // 错误的header头参数
            APP_DEBUG && trace("Wrong user info param.", "DEBUG");
            throw_strack_exception("Wrong user info param.", ErrorCode::WRONG_USER_INFO_PARAM);
        }

        return $next($request);
    }

    /**
     * 获取当前模块编码
     * @param Request $request
     * @return string
     */
    protected function getCurrentModuleCode(Request $request)
    {
        $controller = to_under_score($request->controller());

        if ($controller === 'entity') {
            if (!array_key_exists('module_code', $this->param)) {
                throw_strack_exception('Module parameter does not exist.', ErrorCode::MODULE_PARAM_NOT_EXIST);
            }

            $currentModuleCode = $this->param['module_code'];

            if (!array_key_exists($currentModuleCode, Module::$moduleDictData['module_index_by_code'])) {
                throw_strack_exception('Current module does not exist.', ErrorCode::MODULE_DOES_NOT_EXIST);
            }

        } else {
            if (array_key_exists('module_code', $this->param)) {
                $currentModuleCode = $this->param['module_code'];
            } else {
                $currentModuleCode = $controller;
            }
        }

        return $currentModuleCode;
    }
}
